/* ----------------------------------------------------------------------------
   The Kiwi Toolkit - A Java Class Library
   Copyright (C) 1998-2008 Mark A. Lindner

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this library; if not, see <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------------
*/

package com.hyperrealm.kiwi.event;

import java.util.*;

/** A support object for generating <code>KTreeModelEvent</code>s.
 *
 * @see com.hyperrealm.kiwi.event.KTreeModelEvent
 * @author Mark Lindner
 * @since Kiwi 2.0
 */

public class KTreeModelSupport
{
  private ArrayList<KTreeModelListener> listeners;
  private Object source;

  /** Construct a new <code>KTreeModelSupport</code> object.
   *
   * @param source The owner of this object (and the source of the events that
   * will be generated by it).
   */

  public KTreeModelSupport(Object source)
  {
    listeners = new ArrayList<KTreeModelListener>();
    this.source = source;
  }

  /** Add a <code>KTreeModelListener</code> to this object's list
   * of listeners.
   *
   * @param listener The listener to add.
   */

  public void addTreeModelListener(KTreeModelListener listener)
  {
    synchronized(listeners)
    {
      listeners.add(listener);
    }
  }

  /** Remove a <code>KTreeModelListener</code> from this object's list of
   * listeners.
   *
   * @param listener The listener to remove.
   */

  public void removeTreeModelListener(KTreeModelListener listener)
  {
    synchronized(listeners)
    {
      listeners.remove(listener);
    }
  }

  /** Fire a <i>nodes added</i> event for a range of nodes. Notifies
   * listeners that a range of children have been added to a node.
   *
   * @param parentNode The parent node.
   * @param startIndex The start index of the range of child nodes.
   * @param endIndex The end index of the range of child nodes.
   */

  public void fireNodesAdded(Object parentNode, int startIndex, int endIndex)
  {
    KTreeModelEvent evt = null;

    synchronized(listeners)
    {
      Iterator<KTreeModelListener> iter = listeners.iterator();
      while(iter.hasNext())
      {
        KTreeModelListener l = iter.next();
        
        if(evt == null)
          evt = new KTreeModelEvent(source, parentNode, startIndex, endIndex);
        l.nodesAdded(evt);

      }
    }
  }

  /** Fire a <i>nodes added</i> event for a single node. Notifies
   * listeners that a child has been added to a node.
   *
   * @param parentNode The parent node.
   * @param index The offset of the new child within the parent's list of
   * children.
   */
  
  public void fireNodeAdded(Object parentNode, int index)
  {
    fireNodesAdded(parentNode, index, index);
  }

  /** Fire a <i>nodes removed</i> event for a range of nodes. Notifies
   * listeners that a range of children have been removed from a node.
   *
   * @param parentNode The parent node.
   * @param startIndex The start index of the range of child nodes.
   * @param endIndex The end index of the range of child nodes.
   */

  public void fireNodesRemoved(Object parentNode, int startIndex, int endIndex)
  {
    KTreeModelEvent evt = null;

    synchronized(listeners)
    {
      Iterator<KTreeModelListener> iter = listeners.iterator();
      while(iter.hasNext())
      {
        KTreeModelListener l = iter.next();
        if(evt == null)
          evt = new KTreeModelEvent(source, parentNode, startIndex, endIndex);
        l.nodesRemoved(evt);
      }
    }
  }

  /** Fire a <i>nodes removed</i> event for a single node. Notifies
   * listeners that a child has been removed from a node.
   *
   * @param parentNode The parent node.
   * @param index The offset of the removed child within the parent's list of
   * children.
   */
  
  public void fireNodeRemoved(Object parentNode, int index)
  {
    fireNodesRemoved(parentNode, index, index);
  }
  
  /** Fire a <i>nodes changed</i> event for a range of nodes. Notifies
   * listeners that a range of children of a given node have changed in some
   * perceptible way.
   *
   * @param parentNode The parent node.
   * @param startIndex The start index of the range of child nodes.
   * @param endIndex The end index of the range of child nodes.
   */

  public void fireNodesChanged(Object parentNode, int startIndex, int endIndex)
  {
    KTreeModelEvent evt = null;

    synchronized(listeners)
    {
      Iterator<KTreeModelListener> iter = listeners.iterator();
      while(iter.hasNext())
      {
        KTreeModelListener l = iter.next();
        
        if(evt == null)
          evt = new KTreeModelEvent(source, parentNode, startIndex, endIndex);
        l.nodesChanged(evt);
      }
    }
  }

  /** Fire a <i>node changed</i> event for a single node. Notifies
   * listeners that a child of a given node has changed in some
   * perceptible way.
   *
   * @param parentNode The parent node.
   * @param index The offset of the changed child within the parent's
   * list of children.
   */
  
  public void fireNodeChanged(Object parentNode, int index)
  {
    fireNodesChanged(parentNode, index, index);
  }

  /** Fire a <i>node structure changed</i> event. Notifies listeners that the
   * subtree rooted at the given node has undergone a substantial structural
   * change.
   *
   * @param node The root node of the subtree that has changed.
   */

  public void fireNodeStructureChanged(Object node)
  {
    KTreeModelEvent evt = null;

    synchronized(listeners)
    {
      Iterator<KTreeModelListener> iter = listeners.iterator();
      while(iter.hasNext())
      {
        KTreeModelListener l = iter.next();
        
        if(evt == null)
          evt = new KTreeModelEvent(source, node);
        l.structureChanged(evt);
      }
    }
  }

  /** Fire a <i>data changed</i> event. Notifies listeners that the entire
   * tree structure has changed.
   */
  
  public void fireDataChanged()
  {
    KTreeModelEvent evt = null;

    synchronized(listeners)
    {
      Iterator<KTreeModelListener> iter = listeners.iterator();
      while(iter.hasNext())
      {
        KTreeModelListener l = iter.next();
        
        if(evt == null)
          evt = new KTreeModelEvent(source);
        l.dataChanged(evt);
      }
    }
  }
  
}

/* end of source file */
